package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

func main() {
	//fmt.Println(eval1(10, 10, "*"))
	//fmt.Println(div(13, 3))
	//fmt.Println(apply(pow, 3, 4))
	//匿名函数作为惨素
	//fmt.Println(apply(func(a int, b int) int {
	//	return int(math.Pow(float64(a), float64(b)))
	//}, 3, 4))

	//fmt.Println(sum(1, 2, 3, 4))
	//a, b := 3, 4
	//a, b = swap1(a, b)
	//fmt.Println(a, b)

	//a2, b2 := 3, 4
	//swap2(&a2, &b2)
	//fmt.Println(a2, b2)
}

func swap2(a, b *int) {
	*a, *b = *b, *a
}

func swap1(a, b int) (int, int) {
	return b, a
}

func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	//for _, v := range numbers {
	//	s += v
	//}
	return s
}

func pow(a, b int) int {
	return int(math.Pow(float64(a), float64(b)))
}

func apply(op func(int, int) int, a, b int) int {
	p := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("Calling function %s with args "+"(%d,%d)", opName, a, b)
	return op(a, b)
}

func div(a int, b int) (q, r int) {
	return a / b, a % b
	/*
		q = a / b
		r = a % b
		return
	*/
}

func eval2(a, b int, op string) (int, error) {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		q, _ := div(a, b)
		return q, nil
	default:
		return 0, fmt.Errorf("unsupported operation %s", op)
	}
}
func eval1(a, b int, op string) int {
	switch op {
	case "+":
		return a + b
	case "-":
		return a - b
	case "*":
		return a * b
	case "/":
		return a / b
	default:
		panic("unsupported operation " + op)
	}
}
